﻿namespace UnityEditor
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using UnityEngine;

    internal class AttributeHelper
    {
        private static MonoMenuItem[] ExtractContextMenu(System.Type klass)
        {
            Hashtable hashtable = new Hashtable();
            MethodInfo[] methods = klass.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
            for (int i = 0; i < methods.GetLength(0); i++)
            {
                MethodInfo info = methods[i];
                foreach (ContextMenu menu in info.GetCustomAttributes(typeof(ContextMenu), false))
                {
                    MonoMenuItem item = new MonoMenuItem();
                    if (hashtable[menu.menuItem] != null)
                    {
                        item = (MonoMenuItem) hashtable[menu.menuItem];
                    }
                    item.menuItem = menu.menuItem;
                    item.type = klass;
                    item.execute = info.Name;
                    hashtable[menu.menuItem] = item;
                }
            }
            MonoMenuItem[] itemArray = new MonoMenuItem[hashtable.Count];
            int num3 = 0;
            IEnumerator enumerator = hashtable.Values.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    MonoMenuItem current = (MonoMenuItem) enumerator.Current;
                    itemArray[num3++] = current;
                }
            }
            finally
            {
                IDisposable disposable = enumerator as IDisposable;
                if (disposable == null)
                {
                }
                disposable.Dispose();
            }
            return itemArray;
        }

        private static MonoGizmoMethod[] ExtractGizmos(Assembly assembly)
        {
            ArrayList list = new ArrayList();
            foreach (System.Type type in AssemblyHelper.GetTypesFromAssembly(assembly))
            {
                MethodInfo[] methods = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
                for (int i = 0; i < methods.GetLength(0); i++)
                {
                    MethodInfo info = methods[i];
                    foreach (DrawGizmo gizmo in info.GetCustomAttributes(typeof(DrawGizmo), false))
                    {
                        ParameterInfo[] parameters = info.GetParameters();
                        if (parameters.Length == 2)
                        {
                            MonoGizmoMethod method = new MonoGizmoMethod();
                            if (gizmo.drawnType == null)
                            {
                                method.drawnType = parameters[0].ParameterType;
                            }
                            else
                            {
                                if (!gizmo.drawnType.IsSubclassOf(parameters[0].ParameterType))
                                {
                                    continue;
                                }
                                method.drawnType = gizmo.drawnType;
                            }
                            if ((parameters[1].ParameterType == typeof(GizmoType)) || (parameters[1].ParameterType == typeof(int)))
                            {
                                method.drawGizmo = info;
                                method.options = (int) gizmo.drawOptions;
                                list.Add(method);
                            }
                        }
                    }
                }
            }
            MonoGizmoMethod[] methodArray = new MonoGizmoMethod[list.Count];
            int num4 = 0;
            IEnumerator enumerator = list.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    MonoGizmoMethod current = (MonoGizmoMethod) enumerator.Current;
                    methodArray[num4++] = current;
                }
            }
            finally
            {
                IDisposable disposable = enumerator as IDisposable;
                if (disposable == null)
                {
                }
                disposable.Dispose();
            }
            return methodArray;
        }

        private static MonoMenuItem[] ExtractMenuCommands(Assembly assembly)
        {
            Hashtable hashtable = new Hashtable();
            foreach (System.Type type in AssemblyHelper.GetTypesFromAssembly(assembly))
            {
                MethodInfo[] methods = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
                for (int i = 0; i < methods.GetLength(0); i++)
                {
                    MethodInfo info = methods[i];
                    foreach (UnityEditor.MenuItem item in info.GetCustomAttributes(typeof(UnityEditor.MenuItem), false))
                    {
                        MonoMenuItem item2 = new MonoMenuItem();
                        if (hashtable[item.menuItem] != null)
                        {
                            item2 = (MonoMenuItem) hashtable[item.menuItem];
                        }
                        item2.menuItem = item.menuItem;
                        item2.type = type;
                        if (item.validate)
                        {
                            item2.validate = info.Name;
                        }
                        else
                        {
                            item2.execute = info.Name;
                            item2.index = i;
                            item2.priority = item.priority;
                        }
                        hashtable[item.menuItem] = item2;
                    }
                }
            }
            MonoMenuItem[] array = new MonoMenuItem[hashtable.Count];
            int num4 = 0;
            IEnumerator enumerator = hashtable.Values.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    MonoMenuItem current = (MonoMenuItem) enumerator.Current;
                    array[num4++] = current;
                }
            }
            finally
            {
                IDisposable disposable = enumerator as IDisposable;
                if (disposable == null)
                {
                }
                disposable.Dispose();
            }
            Array.Sort(array, new CompareMenuIndex());
            return array;
        }

        internal static ArrayList FindEditorClassesWithAttribute(System.Type attrib)
        {
            ArrayList list = new ArrayList();
            IEnumerator<System.Type> enumerator = EditorAssemblies.loadedTypes.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    System.Type current = enumerator.Current;
                    if (current.GetCustomAttributes(attrib, false).Length != 0)
                    {
                        list.Add(current);
                    }
                }
            }
            finally
            {
                if (enumerator == null)
                {
                }
                enumerator.Dispose();
            }
            return list;
        }

        private static string GetComponentMenuName(System.Type klass)
        {
            object[] customAttributes = klass.GetCustomAttributes(typeof(AddComponentMenu), false);
            if (customAttributes.Length > 0)
            {
                AddComponentMenu menu = (AddComponentMenu) customAttributes[0];
                return menu.componentMenu;
            }
            return null;
        }

        internal static object InvokeMemberIfAvailable(object target, string methodName, object[] args)
        {
            MethodInfo method = target.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
            if (method != null)
            {
                return method.Invoke(target, args);
            }
            return null;
        }

        internal static void InvokeMethod(System.Type type, string methodName, object[] arguments)
        {
            MethodInfo method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
            if (method != null)
            {
                method.Invoke(null, arguments);
            }
        }

        internal static void InvokeStaticMethod(System.Type type, string methodName, object[] arguments)
        {
            MethodInfo method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
            if (method != null)
            {
                method.Invoke(null, arguments);
            }
        }

        internal class CompareMenuIndex : IComparer
        {
            int IComparer.Compare(object xo, object yo)
            {
                AttributeHelper.MonoMenuItem item = (AttributeHelper.MonoMenuItem) xo;
                AttributeHelper.MonoMenuItem item2 = (AttributeHelper.MonoMenuItem) yo;
                if (item.priority != item2.priority)
                {
                    return item.priority.CompareTo(item2.priority);
                }
                return item.index.CompareTo(item2.index);
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct MonoGizmoMethod
        {
            public MethodInfo drawGizmo;
            public System.Type drawnType;
            public int options;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct MonoMenuItem
        {
            public string menuItem;
            public string execute;
            public string validate;
            public int priority;
            public int index;
            public System.Type type;
        }
    }
}

